package org.droidcon.apps.template.io.json;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.droidcon.apps.template.io.XmlHandler;
import org.droidcon.apps.template.io.XmlHandler.HandlerException;
import org.xmlpull.v1.XmlPullParser;

import android.content.ContentResolver;

import com.google.gson.stream.JsonReader;

public class RemoteJsonExecutor {
	private final HttpClient mHttpClient;
	private final ContentResolver mResolver;

	public RemoteJsonExecutor(HttpClient httpClient, ContentResolver resolver) {
		mHttpClient = httpClient;
		mResolver = resolver;
	}

	/**
	 * Execute a {@link HttpGet} request, passing a valid response through
	 * {@link XmlHandler#parseAndApply(XmlPullParser, ContentResolver)}.
	 */
	public void executeGet(String url, JsonHandler handler)
			throws HandlerException {
		final HttpUriRequest request = new HttpGet(url);
		execute(request, handler);
	}

	/**
	 * Execute this {@link HttpUriRequest}, passing a valid response through
	 * {@link XmlHandler#parseAndApply(XmlPullParser, ContentResolver)}.
	 */
	public void execute(HttpUriRequest request, JsonHandler handler)
			throws HandlerException {
		try {
			final HttpResponse resp = mHttpClient.execute(request);
			final int status = resp.getStatusLine().getStatusCode();
			if (status != HttpStatus.SC_OK) {
				throw new HandlerException("Unexpected server response "
						+ resp.getStatusLine() + " for "
						+ request.getRequestLine());
			}
			
			final InputStream input = resp.getEntity().getContent();
			try {
				 JsonReader reader = new JsonReader(new InputStreamReader(input, "UTF-8"));			        
  	        	 handler.parseAndApply(reader, mResolver);
  	        	 reader.close();
			} finally {
				if (input != null)
					input.close();
			}
		} catch (HandlerException e) {
			throw e;
		} catch (IOException e) {
			throw new HandlerException("Problem reading remote response for "
					+ request.getRequestLine(), e);
		}
	}
}
